昨天,我們成功的在 CG 上創建了一個 PixiJS 的專案,並寫出了第一個測試程式。今天,就讓我們正式踏入 PixiJS 的世界,來認識最核心的顯示物件——Sprite。
在 PixiJS 中,Sprite
是最基本的顯示物件,用於在畫面中顯示圖像,像是玩家角色、敵人、子彈,甚至是背景中的一顆樹、背景本身,它們絕大多數都是由 Sprite
構成的。簡單來說,只要是你看得到的圖像,通常都是一個 Sprite
。
首先,我們需要將圖片載入到專案中。點擊專案右側欄上,如圖示的按鈕,即可打開 資源管理 頁面。這裡會顯示你專案內所有已載入的資源,並且按照分類顯示。接著點擊上方的「加載資源」。
開啟資源頁面後,你必須先給這個資源一個代理名字,前綴的專案代碼是固定的,後面是我們可以自己取的別名,我個人的習慣是會先加上資源的類型,然後再寫上資源的名稱,例如 圖片.女巫。
有了名字之後,在 搜尋關鍵字 欄位輸入 hag-broom 並點選「圖片」分類,應該會找到由 Haskasu 上傳,一個騎著掃帚的女巫圖片,點擊資源的勾選框後,再點擊下方的「加載資源」即可將該圖片載入至專案中。
載入完成後,該圖片就會顯示在剛剛打開的資源管理頁面中,點擊即可顯示該資源的詳細資訊。
接著讓我們來更新 app.ts
裡面的程式碼,先將昨天寫的程式碼全部清空,並貼上下方的程式碼。這段程式碼將會載入我們剛剛加入的圖片,並在畫面中央顯示出來。
import pixi = CG.Pixi.pixi;
async function start() {
// 將專案資源載入至遊戲中,並等待載入完成。
// (記得將資源別名修改成你自己專案的資源別名喔!)
await pixi.assets
.add("ironman2025_cook.圖片.女巫")
.load();
// 初始化 Pixi。
await pixi.initialize({
stageWidth: 960,
stageHeight: 540
});
// 使用資源別名創建 Sprite 物件,並設定物件縮放、錨點、位置。
const sprite = pixi.assets.createSprite("ironman2025_cook.圖片.女巫");
sprite.scale.set(3);
sprite.anchor.set(0.5);
sprite.position.set(pixi.stageWidth * 0.5, pixi.stageHeight * 0.5);
// 將 Sprite 物件加入到舞台中。
pixi.root.addChild(sprite);
}
start();
完成後,點擊上方的「試玩遊戲」按鈕,你就會看到女巫圖片出現在遊戲畫面中央了!
如圖所示,你可以看到女巫被正確的加入到了舞台的中央,接下來我們來一一拆解程式碼到底做了哪些事情吧!
如果你還不會 TypeScript 或 JavaScript 也沒關係,我會簡單的帶過一些基礎的語法,讓妳也能夠大概了解各個程式碼的用途!
import
函式庫import pixi = CG.Pixi.pixi;
這行程式碼是將 CG.Pixi.pixi
這一長串縮寫成 pixi
,因為我們會常常需要用到 CG.Pixi.pixi
裡面的功能,例如範例中使用的 assets
、initialize
、root
等,要是每次使用前面都得寫這麼長,是我就累了。
讓我們用實際的範例來示範一下,有沒有 import
的差別在哪裡。
// 沒有使用 import 的時候
sprite.position.set(CG.Pixi.pixi.stageWidth * 0.5, CG.Pixi.pixi.stageHeight * 0.5);
// 使用 import 的時候
sprite.position.set(pixi.stageWidth * 0.5, pixi.stageHeight * 0.5);
是不是縮短很多,怎麼樣,知道 import
的美好了吧!而且更讚的是,當你輸入 pixi
後,CG 會自動跳出提示,選擇後 CG 就會幫你在檔案最上方補上那一段 import
,也就是說其實那一段其實是 CG 幫我寫的,我們其實不需要去管要不要 import
的事情。
不過實際上
import
的功能其實是「引用」才對,一般來說想要使用函示庫或模組的功能,第一件事情就是先引用到當前的檔案中。只是在 CG,所有的模組都會被包裝在CG
這個全域物件內,所以才能直接利用CG.Pixi.pixi
這樣的方式來使用。
async
函數 & awiat
function start() {
// ... 暫時省略 ...
}
這是一般用來創建 function(函數)的方法,你可以把函數想像成是一道食譜,上面寫好了各種步驟,用來讓我們可以跟著食譜一步步的做。
但它終究是一道食譜,只是定義好步驟而已,要執行這些步驟,我們需要實際動手。
start();
這樣就是告訴電腦,開始執行名叫 start
的函數,電腦就會從頭到尾,一步步地執行裡面的程式碼。
async function start() {
// 將專案資源載入至遊戲中,並等待載入完成。
await pixi.assets.add("ironman2025_cook.圖片.女巫").load();
// ... 暫時省略 ...
}
那 function
前面加個 async
是什麼意思?也就是告訴電腦,這個函數裡面有需要等待的步驟,這個步驟執行需要一段時間,必須等它執行完成以後,才可以繼續往下走。
await
就是告訴電腦,這裡就是要等待的步驟,當函數執行到這裡的時候,就會開始等待,直到後面的程式碼告訴電腦說「我執行完了!」,這個函數才會繼續往下執行其他程式碼。
需要特別注意的是,
await
只能在async
函數裡面使用,而想要使用await
,就必須將函數標記成async
函數喔!
// 將專案資源載入至遊戲中,並等待載入完成。
await pixi.assets
.add("ironman2025_cook.圖片.女巫")
.load();
PixiJS 提供了載入資源的功能,而 CG 又幫我們把這個功能包裝成更簡單的函數。
pixi.assets.add()
:在 ()
內輸入專案的資源別稱,就可以將資源加入到準備載入的行列中,資源的別稱可以在資源管理內查看,每個資源上方都會有我們載入資源時所填寫的別稱,旁邊還會有個「複製」按鈕,點擊後就可以直接填在括號內。記得字串一定要在前後使用
"
雙引號包起來喔!
pixi.assets.load()
:使用 add()
加入要載入的資源後,就要使用 load()
開始載入資源,這個步驟需要花點時間,因此需要在前面加上 await
來等待載入完成。由於
add()
執行後會回傳pixi.assets
,因此我們才可以繼續使用pixi.assets
的功能,而不需要重複撰寫pixi.assets
開頭。
// 初始化 Pixi。
await pixi.initialize({
stageWidth: 960,
stageHeight: 540
});
想要利用 Pixi 在畫面上顯示東西,就必須先初始化。
pixi.initialize()
用於初始化 Pixi 的舞台設定,它會接收一個物件作為參數,在物件內我們可以設定 stageWidth
、stageHeight
,也就是舞台寬度、舞台高度。其餘還有像是 resolution
、stageMask
等屬性,不過這些等之後遇到了再來介紹!
這個步驟同樣需要一點時間,因此我們也要在前面加上 await
告訴電腦請等它執行完畢。
// 使用資源別名創建 Sprite 物件,並設定物件縮放、錨點、位置。
const sprite = pixi.assets.createSprite("ironman2025_cook.圖片.女巫");
sprite.scale.set(3);
sprite.anchor.set(0.5);
sprite.position.set(pixi.stageWidth * 0.5, pixi.stageHeight * 0.5);
pixi.assets.createSprite()
用於快速的幫我們創建一個 Sprite 物件,創建完成後我們會用 sprite
這個名字把物件保存起來。
如果你習慣使用
Texture
來創建物件,也可以這樣做。const texture = pixi.assets.getTexture("ironman2025_cook.圖片.女巫");
const sprite = new PIXI.Sprite(texture);
接著我們對這個物件做了三件事情:
scale.set()
:用於設定物件的縮放,預設為 1
,set(3)
表示將這個物件放大 3 倍。anchor.set()
:用於設定物件的錨點(中心點),預設為 0
,也就是物件的錨點預設是在左上角,set(0.5)
表示將物件的錨點設定在正中間。當然如果設定為 1
,就是將錨點設定在物件的右下角。position.set()
:用於設定物件的位置,預設為 (0, 0),也就是舞台畫面的左上角,x 越大物件越靠右邊,y 越大物件越靠下方,pixi.stageWidth
、pixi.stageHeight
分別代表我們在初始化舞台時所設定的寬高,* 0.5
則代表各自取一半(寬的一半與高的一半),因此就會是畫面的正中央。其實這些具有
x
、y
的屬性,完整的set
寫法應該會是sprite.anchor.set(0.5, 0.5)
這樣,表示x
設為0.5
,y
也設為0.5
,只是 PixiJS 在我們省略第二個參數的時候,就會自動認為我們要將x
跟y
都設定成那一個參數,因此在設定scale
、anchor
中,我省略了第二個參數。
// 將 Sprite 物件加入到舞台中。
pixi.root.addChild(sprite);
這是最關鍵的一步。在 PixiJS 中,所有要顯示在畫面上的物件,都必須被「加入到舞台」上。pixi.root
就是我們的主舞台,addChild()
則是用來將物件放上去。如果你忘記寫這行,就算你前面做了再多設定,也無法在畫面上看到任何東西喔!
在原生 PixiJS 中,根節點通常是
app.stage
,如果是在寫原生的 PixiJS,上面看起來會像是app.stage.addChild(sprite)
。pixi.root
是站長為了模擬以前在 Flash 上開發遊戲的習慣,所以將根節點取名為root
。
今天的內容比昨天豐富了許多,我們不僅認識了遊戲的核心物件 Sprite,更手把手地將一個完整的 Sprite
物件顯示在畫面上,並且拆解了程式碼的每個部分。
如果你是曾接觸過 PixiJS 的人,你可能會發現有許多部分與原生的 PixiJS 有所不同,因為我們的 PixiJS 是建立在 CG 平台上的,這裡的 Pixi 模組幫我們把一些本應該自己設定的部分,包裝成了更簡潔的函數供我們使用,這也是我為什麼選擇在這個平台上介紹的原因,這降低了許多新手的門檻,我認為等大家真的了解了 PixiJS 的運作流程後,再去接觸原生的 PixiJS 語法也不遲。
從明天開始,我們將會真正讓這個 Sprite 動起來,介紹如何控制它的位置、縮放與旋轉!